Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Inheritance

Îåêßíçóå áðü ôï ìÝëïò Χρήστος Γεωργακόπουλος. Τελευταία δημοσίευση από το μέλος Χρήστος Γεωργακόπουλος στις 02-02-2006, 11:45. Υπάρχουν 9 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  02-02-2006, 10:30 9145

    Inheritance

    Θέλω να φτιάξω μια mustinherit κλάση (ή ένα interface) η οποία θα γίνεται inherit (ή implement) από κάποιες άλλες, προκειμένου να εξασφαλίσω ότι οι inherited κλάσεις θα έχουν κάποιο ελάχιστο functionality.

    Θέλω πχ, όλες οι child κλάσεις να έχουν μια μέθοδο SaveObject(object As BaseObject), αλλά όχι με BaseObject, αλλά με κάποια κλάσεις που κάνουν inherit το BaseObject.

    Το ιδανικό μου θα ήταν, να έχω ένα interface που να έχει το εξής declaration:

    Sub SaveObject(object As BaseObject)

    και οι κλάσεις που κάνουν implement το interface να έχουν:

    Sub SaveObject(object as CustomObject) implements IMyInterface.SaveObject

    όπου βεβαίως το CustomObject κάνει inherit το BaseObject.

    Πως;

     


    Χρήστος Γεωργακόπουλος
  •  02-02-2006, 11:10 9146 σε απάντηση της 9145

    Απ: Inheritance

    Σε C#, πάει κάπως έτσι:

    public abstract class BaseObject {

                  public virtual void SaveObject(BaseObject obj) {

                         Console.WriteLine("lililili");
                  }
           }
          

           public class DerivedObject : BaseObject {      

                  public new void SaveObject(DerivedObject obj){

                         Console.WriteLine("lalalala");
                  }
           }

      άν δε με απατά η μνήμη μου ( και ... "πιστεύω πως δε με απατά"  - famous last words) σε VB είανι το ίδιο, μόνο που όπου abstract βάνουμε MustInherit, κι όπου new βάνουμε Shadows κι όπου virtual βάνουμε overridable.

    Τώρα, αν δείς μετά την κλάσση σου με intellisense, θα σου δείξει δυστυχώς και τις δύο μεθόδους, και ο developer έχει την ευχέρεια να καλέσει οποιαδήποτε απ'τις δύο. Δε νόμίζω όμως οτι μπορείς να κάνεις κάτι παραπάνω απ'αυτο αν κρίνω κι απ'το intellisense σε framework classes, όπου έχω δεί την ίδια συμπεριφορά.

    Καλή μας μέρα, μιας κι έβγαλε και ήλιο σήμερα ...

    Angel
    O:]
  •  02-02-2006, 11:10 9147 σε απάντηση της 9145

    Απ: Inheritance

    Το έλυσα προσωρινά με inherit και δήλωση της παραμέτρου σαν object. Στις child κλάσεις μόλις παίρνω το object κάνω cast στον τύπο που θέλω. Αλλά αν υπήρχε κάποιος κομψότερος τρόπος θα με ενδιέφερε...
    Χρήστος Γεωργακόπουλος
  •  02-02-2006, 11:15 9148 σε απάντηση της 9145

    Απ: Inheritance

    Αυτό που θέλεις να κάνεις δεν είναι εφικτό, γιατί όταν υλοποιείς ένα interface ή κάνεις override μια virtual function πρέπει να σεβαστείς 100% το prototype της, οπότε δεν μπορείς να αλλάξεις τον τύπο των παραμέτρων.

    Αν κατάλαβα καλά, αυτό που θέλεις να κάνεις είναι το (;;; ποιο είναι το όνομά του; δεν έχω το GoF εδώ) pattern, στο οποίο έχεις δύο παράλληλες ιεραρχίες κλάσεων: Α και Β, και κάθε μια από τις κλάσεις της Β υλοποιεί ορισμένες λειτουργίες πάνω στην αντίστοιχη κλάση της Α.

    Στην περίπτωση αυτή, όλες οι κλάσεις της B θα κάνουν override την DoSomething(BaseA) και θα την υλοποιούν για κάποιο DerivedA. Θέλεις λοιπόν:

    • Μια factory κλάση που για το κάθε Α σου δίνει το κατάλληλο Β
    • Έναν τρόπο σε όλες τις υλοποιήσεις της DoSomething που ελέγχει ότι το BaseA που του έχει περαστεί σαν παράμετρος είναι του σωστού τύπου. Αυτό μπορείς να το κάνεις είτε στατικά (με κώδικα) είτε π.χ. βάζοντας σε όλες τις DerivedB κλάσεις ένα δικό σου attribute που να λέει σε ποια DerivedA αντιστοιχεί, και την BaseB.DoSomething να διασταυρώνει το attribute αυτό με τον πραγματικό τύπο της παραμέτρου της.

    Αν θέλεις sample κώδικα πες το.

     


    Νατάσα Μανουσοπούλου
  •  02-02-2006, 11:16 9149 σε απάντηση της 9147

    Απ: Inheritance

    Το virtual (overridable) μου λέει ότι αν θέλει η child κλάση μπορεί να κάνει override, αλλά δεν την υποχρεώνει να το κάνει. Εγώ θέλω να την υποχρεώσω. (Είμαι αυστηρός με τις κλάσεις μου.. με καρότο και μαστίγιο τις έχω :-)
    Χρήστος Γεωργακόπουλος
  •  02-02-2006, 11:17 9150 σε απάντηση της 9146

    Απ: Inheritance

    ... τώρα βέβαια που το ξαναβλέπω, συνειδητοποιώ οτι δε λύνει το πρόβλημά σου αυτό, δεν κάνει δηλαδή force τον overrider να κάνει implement τη μέθοδο που θές, με τις παραμέτρους που θές.

    Σαν εναλλακτική, προτείνω κάποια runtime type checks στη base class, έτσι ώστε να σιγουρεύεις οτι η παράμετρος είναι του σωστού τύπου, σε συνδυασμό με κάποιες άλλες MustOverride μεδόδους χωρίς παραμέτρους. Ίσως λίγο αργότερα βρώ λίγο χρόνο να κοιτάξω κάποιες περιπτώσεις και κάνω post κάποιο παράδειγμα.
    Angel
    O:]
  •  02-02-2006, 11:19 9151 σε απάντηση της 9148

    Απ: Inheritance

     mns wrote:
    • Μια factory κλάση που για το κάθε Α σου δίνει το κατάλληλο Β
    • Έναν τρόπο σε όλες τις υλοποιήσεις της DoSomething που ελέγχει ότι το BaseA που του έχει περαστεί σαν παράμετρος είναι του σωστού τύπου. Αυτό μπορείς να το κάνεις είτε στατικά (με κώδικα) είτε π.χ. βάζοντας σε όλες τις DerivedB κλάσεις ένα δικό σου attribute που να λέει σε ποια DerivedA αντιστοιχεί, και την BaseB.DoSomething να διασταυρώνει το attribute αυτό με τον πραγματικό τύπο της παραμέτρου της.

    Αν θέλεις sample κώδικα πες το.

    Ανατριχιαστικό ακούγεται, αλλά δώσε sample αν έχεις κάτι πρόχειρο. thanx.


    Χρήστος Γεωργακόπουλος
  •  02-02-2006, 11:27 9152 σε απάντηση της 9145

    Απ: Inheritance

    Καταρχήν να ζητήσω συγνώμη αλλά δεν είμαι πολύ εξοικιωμένος με VB.
    Εν συνεχεία να ρωτήσω γιατί χρειάζεσαι να περάσεις σαν παράμετρο στη SaveObject ένα instance του object αφού έχεις ήδη πρόσβαση σε αυτό μέσω του this (C#) ή του me στη VB;
    Αν έχω καταλάβει κάτι από αυτό που θέλεις να κάνεις κάτι τέτοιο ίσως σε βοηθήσει:
    public interface BaseObject
    {
    public void SaveObject();
    }

    public class CustomObject : BaseObject
    {
    private int id;
    private string name;

    public void SaveObject()
    {
    //Persist properties using this accessor
    //this.id
    //this.name
    }
    }
    Ελπίζω να σε βοήθησα...
    MSc Konstantinos Pantos
    MCP Software Engineer
    http://blog.pantos.name
    http://kostas.pantos.name
  •  02-02-2006, 11:42 9153 σε απάντηση της 9151

    Απ: Inheritance

     cgeo wrote:

    Ανατριχιαστικό ακούγεται, αλλά δώσε sample αν έχεις κάτι πρόχειρο. thanx.

    Καταλαβαίνω ότι προτιμάς VB αλλά δεν την αντέχω Smile [:)]



    namespace ParallelHierarchies
    {
     public class AllowedBAttribute : System.Attribute
     {
      public AllowedBAttribute(System.Type a_Class)
      {
       Class = a_Class;
      }
      
      public readonly System.Type Class;
     }

     public class BaseA
     {
      public BaseA()
      {
       Name = this.GetType().ToString();
      }

      public readonly string Name;
     }

     [AllowedB(typeof(DerivedB))]
     public class DerivedA : BaseA
     {
     }

     public class BaseB
     {
      public virtual void Doit(BaseA a)
      {
       object[] attributes = a.GetType().GetCustomAttributes(typeof(AllowedBAttribute), false);
       if (attributes.Length == 0)
        return;

       AllowedBAttribute attribute = attributes[0] as AllowedBAttribute;
       if (this.GetType() != attribute.Class)
        throw new System.ArgumentException(
         string.Format("B class should be of type {0}, is of type {1}",
          attribute.Class.FullName,
          this.GetType().FullName),
         "a");
      }
     }

     public class DerivedB : BaseB
     {
      public override void Doit(BaseA a)
      {
       base.Doit(a);
       // Do something else
      }
     }

     public class DerivedB2 : BaseB
     {
      public override void Doit(BaseA a)
      {
       base.Doit(a);
       // Do something else
      }
     }
    }

    Στο παρακάτω δείγμα, το πρώτο Doit πετυχαίνει, το δεύτερο ρίχνει exception:



       BaseA a = new DerivedA();
       BaseB b = new DerivedB();
       b.Doit(a);

       b = new DerivedB2();
       b.Doit(a);


    Νατάσα Μανουσοπούλου
  •  02-02-2006, 11:45 9154 σε απάντηση της 9153

    Απ: Inheritance

     mns wrote:

    Καταλαβαίνω ότι προτιμάς VB αλλά δεν την αντέχω Smile [:)]

    Όχι, όχι, με την C# δεν έχω κανένα πρόβλημα. Την μιλάω, απλά δεν είναι η μητρική μου γλώσσα. Έτσι κι αλλιώς έχω ανοιχτό τον translator από πίσω...

    Thanx, πάντως, θα δω τον κώδικα αργότερα.


    Χρήστος Γεωργακόπουλος
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems